package run;


import base.*;
import java.util.ArrayList;

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.text.*;
import javax.swing.border.Border;

import java.io.File;
import javax.sound.sampled.*;

public class PlayScreen extends JPanel {
	// --------DATA----------
	private SolverGrid gridPlay;
	private int maxScore = 0;
	private int totalScore = 0;
	private int fullTime;
	private boolean isFinish = false;
	private boolean keyTrue = false;
	private Clock clock;
	private Timer timer;

	// ---------GUI------------
	private Box vertBox;
	private Box topBox;
	private Box bottomBox;
	private Box clueBox;
	private Box scoreBox;
	private Box timeBox;
	private Box boxButtons;
	private JLabel scoreLabel = new JLabel("        ", new ImageIcon(this
			.getClass().getResource("/img/result.png")), JLabel.CENTER);
	private JLabel timeLabel = new JLabel("     ", new ImageIcon(this
			.getClass().getResource("/img/clock.png")), JLabel.CENTER);
	private JTextPane clueTextPane = new JTextPane();
	private JTextPane scoreTextPane = new JTextPane();
	private JTextPane timeTextPane = new JTextPane();
	private JScrollPane scrollPane;

	private JButton btnHint = new JButton("Hint", new ImageIcon(this.getClass()
			.getResource("/img/hint.png")));
	private JButton btnCheck = new JButton("Check", new ImageIcon(this
			.getClass().getResource("/img/check.png")));
	private JButton btnClue = new JButton("Clue", new ImageIcon(this.getClass()
			.getResource("/img/nextclue.png")));
	private JButton btnSolution = new JButton("Solve", new ImageIcon(this
			.getClass().getResource("/img/solution.png")));
	private JButton btnFinish = new JButton("Finish", new ImageIcon(this
			.getClass().getResource("/img/finish.png")));

	private Border brdThinGray = BorderFactory.createLineBorder(Color.BLACK, 1);
	private static int MARGIN_GAP = 10;

	public PlayScreen(Crossword cw) {
		this.setLayout(new BorderLayout());
		Crossword cwPlay = cw;
		gridPlay = new SolverGrid(cw);
		displayGrid();
		gridPlay.setCrossword(cw);
		gridPlay.repopulateWords();

		// remove all listeners
		gridPlay.removeListeners();
		gridPlay.removeKeyListener(gridPlay.getKeyListeners()[0]);
		gridPlay.init();
		this.maxScore = 100 + 10 + 15 * ((cwPlay.getWords()).size() - 1);
		validate();

		try {
			jbInit();
		} catch (Exception ex) {
			// ex.printStackTrace();
		}
		addListeners();

	}

	private void addListeners() {
		btnHint.addActionListener(new ButtonListener());
		btnSolution.addActionListener(new ButtonListener());
		btnCheck.addActionListener(new ButtonListener());
		btnClue.addActionListener(new ButtonListener());
		btnFinish.addActionListener(new ButtonListener());
		ArrayList squares = gridPlay.getSquares();
		for (int i = 0; i < squares.size(); i++) {
			Square s = (Square) squares.get(i);
			s.addMouseListener(new SquareListener());
		}
	}

	private JTextPane createScore() {
		JTextPane temp = new JTextPane();
		temp.setEditable(false);
		StyledDocument doc = temp.getStyledDocument();
		doc = setTimeStyle(doc);
		try {
			doc.insertString(0, "      0" + totalScore, doc.getStyle("special"));
		} catch (Exception e) {
		}
		return temp;
	}

	private JTextPane createTime() {
		JTextPane temp = new JTextPane();
		clock = new Clock(gridPlay.getCrossword().getMin(), gridPlay
				.getCrossword().getSec());
		fullTime = clock.getMaxMin() * 60 + clock.getMaxSec();
		temp.setEditable(false);
		StyledDocument doc = temp.getStyledDocument();
		doc = setTimeStyle(doc);
		try {
			doc.insertString(0, "  " + clock.toString(), doc
					.getStyle("special"));
		} catch (Exception e) {
		}
		return temp;
	}

	private StyledDocument setTimeStyle(StyledDocument doc) {
		Style special = doc.addStyle("special", StyleContext
				.getDefaultStyleContext().getStyle(StyleContext.DEFAULT_STYLE));
		StyleConstants.setBold(special, true);
		StyleConstants.setAlignment(special, StyleConstants.ALIGN_CENTER);
		StyleConstants.setFontSize(special, 25);
		return doc;
	}

	private void displayGrid() {
		gridPlay.Build();
		add(gridPlay, BorderLayout.CENTER);
	}

	private void nextClue() {
		if (gridPlay.getClueUsed() == 1) {
			String s2 = gridPlay.getSelectedClue2();
			clueTextPane.setText(s2);
			gridPlay.setClueUsed(2);
		} else if (gridPlay.getClueUsed() == 2) {
			String s3 = gridPlay.getSelectedClue3();
			clueTextPane.setText(s3);
			gridPlay.setClueUsed(3);
		}

	}

	private int timeUse() {
		return (fullTime - clock.getMin() * 60 - clock.getSec());
	}

	private int bonusScore()
	{
		int bonus = 0;
		if (keyTrue||gridPlay.getKeyTrue()) {
			if (timeUse() <= fullTime / 4)
				bonus = 20;
			else if (timeUse() <= fullTime / 2)
				bonus = 10;
		}
		return bonus;
	}

	private void playSound(String filename) {
		try {
			AudioInputStream audioInput = AudioSystem
					.getAudioInputStream(new File(filename));
			Clip buttonClickSound;
			buttonClickSound = AudioSystem.getClip();
			buttonClickSound.open(audioInput);
			buttonClickSound.start();
		} catch (Exception ex) {
			ex.printStackTrace();
		}

	}

	private void jbInit() throws Exception {
		this.setBackground(new Color(174, 190, 212));

		vertBox = Box.createVerticalBox();
		topBox = Box.createHorizontalBox();
		bottomBox = Box.createHorizontalBox();

		gridPlay.setPreferredSize(new Dimension(580, 500));

		clueBox = Box.createHorizontalBox();
		clueBox.setPreferredSize(new Dimension(380, 80));

		scoreBox = Box.createVerticalBox();
		scoreBox.setPreferredSize(new Dimension(60, 50));

		timeBox = Box.createVerticalBox();
		timeBox.setPreferredSize(new Dimension(60, 50));

		clueTextPane.setBorder(brdThinGray);
		clueTextPane.setEditable(false);
		clueTextPane.setFont(new Font("Arial", Font.CENTER_BASELINE, 15));
		clueTextPane.setText(gridPlay.getThemeName(gridPlay.getCrossword()));
		scrollPane = new JScrollPane(clueTextPane);

		timeTextPane = createTime();
		timeTextPane.setBackground(new Color(174, 190, 212));
		scoreTextPane = createScore();
		scoreTextPane.setBackground(new Color(174, 190, 212));

		timeLabel.setHorizontalTextPosition(JLabel.LEFT);

		scoreLabel.setHorizontalTextPosition(JLabel.LEFT);

		boxButtons = Box.createHorizontalBox();
		boxButtons.setBackground(new Color(199, 223, 236));

		btnCheck.setMaximumSize(new Dimension(110, 38));
		btnCheck.setPreferredSize(new Dimension(110, 38));
		btnClue.setMaximumSize(new Dimension(110, 38));
		btnClue.setPreferredSize(new Dimension(110, 38));
		btnHint.setMaximumSize(new Dimension(110, 38));
		btnHint.setPreferredSize(new Dimension(110, 38));
		btnSolution.setMaximumSize(new Dimension(110, 38));
		btnSolution.setPreferredSize(new Dimension(110, 38));
		btnFinish.setMaximumSize(new Dimension(110, 38));
		btnFinish.setPreferredSize(new Dimension(110, 38));

		topBox.add(Box.createHorizontalStrut(MARGIN_GAP));
		topBox.add(gridPlay);
		topBox.add(Box.createHorizontalStrut(MARGIN_GAP));
		bottomBox.add(scoreBox);
                    scoreBox.add(Box.createHorizontalStrut(MARGIN_GAP));
                    scoreBox.add(scoreLabel, CENTER_ALIGNMENT);
                    scoreBox.add(scoreTextPane);

		bottomBox.add(clueBox);
                    clueBox.add(Box.createHorizontalStrut(MARGIN_GAP));
                    clueBox.add(scrollPane);
                    clueBox.add(Box.createHorizontalStrut(MARGIN_GAP));
		bottomBox.add(timeBox);
                    timeBox.add(timeLabel, CENTER_ALIGNMENT);
                    timeBox.add(timeTextPane);
                    timeBox.add(Box.createHorizontalStrut(MARGIN_GAP));
                    vertBox.add(Box.createVerticalStrut(MARGIN_GAP));
		vertBox.add(topBox);
		vertBox.add(Box.createVerticalStrut(MARGIN_GAP));
		vertBox.add(bottomBox);
		vertBox.add(Box.createVerticalStrut(MARGIN_GAP));
		vertBox.add(boxButtons);
                    boxButtons.add(Box.createHorizontalStrut(MARGIN_GAP));
                    boxButtons.add(btnCheck);
                    boxButtons.add(Box.createHorizontalStrut(MARGIN_GAP));
                    boxButtons.add(btnHint);
                    boxButtons.add(Box.createHorizontalStrut(MARGIN_GAP));
                    boxButtons.add(btnClue);
                    boxButtons.add(Box.createHorizontalStrut(MARGIN_GAP));
                    boxButtons.add(btnSolution);
                    boxButtons.add(Box.createHorizontalStrut(MARGIN_GAP));
                    boxButtons.add(btnFinish);
                    boxButtons.add(Box.createHorizontalStrut(MARGIN_GAP));
                    vertBox.add(Box.createVerticalStrut(MARGIN_GAP));
		add(vertBox, BorderLayout.CENTER);

		TimeListener t = new TimeListener();
		timer = new Timer(1000, t);
		timer.start();

	}

	class TimeListener implements ActionListener {

		StyledDocument doc = timeTextPane.getStyledDocument();

		public void actionPerformed(ActionEvent e) {
			try {
				if (clock.getMin() == 0 && clock.getSec() == 0) {
					timer.stop();
					isFinish = true;
					playSound("sound/time.wav");
					JOptionPane.showMessageDialog(topBox,
							 "Bạn được   : "+totalScore+" điểm\n"+

							 "Hoàn thành : "+(bonusScore()+totalScore)*100/maxScore+" %\n"

							,"Time up",JOptionPane.INFORMATION_MESSAGE,new ImageIcon(this.getClass().getResource("/img/time.png")));

				} else {
					doc.remove(0, doc.getLength());
					doc.insertString(0, "  " + clock.decrease().toString(), doc
							.getStyle("special"));
				}
			} catch (Exception m) {
			}
			;
		}
	}

	class ButtonListener implements ActionListener {
		@SuppressWarnings("empty-statement")
		public void actionPerformed(ActionEvent e) {
			StyledDocument doc = scoreTextPane.getStyledDocument();
			try {
				if (e.getSource() == btnCheck) {
					if (gridPlay.checkIsCorrect()) {
						playSound("sound/true.wav");
						if (gridPlay.getSelectedWord().getWord().equals(
								gridPlay.getKey().getWord())) {
							totalScore += 100;
							keyTrue = true;
						} else
							switch (gridPlay.getClueUsed()) {
							case 1:
								totalScore += 15;
								break;
							case 2:
								totalScore += 10;
								break;
							case 3:
								totalScore += 5;
								break;
							}
						doc.remove(0, doc.getLength());
						doc.insertString(0, "      " + totalScore, doc
								.getStyle("special"));
					} else
						playSound("sound/false.wav");
				} else if (e.getSource() == btnHint) {
					if (!gridPlay.getSelectedWord().getIsHint()) {
						playSound("sound/hint.wav");
						if (gridPlay.getSelectedWord() == gridPlay.getKey()) {
							clueTextPane.setText(gridPlay.getKeywordClue());
							totalScore -= 20;
							gridPlay.getKey().setIsEditable(true);
                                                        gridPlay.requestFocus();
						} else {
							gridPlay.hintWord();
							totalScore -= 10;
							gridPlay.getSelectedWord().setIsEditable(false);
						}
						gridPlay.getSelectedWord().setIsHint(true);
						doc.remove(0, doc.getLength());
						doc.insertString(0, "      " + totalScore, doc
								.getStyle("special"));
					}
				} else if (e.getSource() == btnClue) {
					nextClue();
					playSound("sound/clue.wav");
                                        gridPlay.requestFocus();
				} else if (e.getSource() == btnSolution) {
					if (isFinish) {
						playSound("sound/solve.wav");
						gridPlay.showSolution();
					} else
						JOptionPane
								.showMessageDialog(null,
										"Bạn chưa kết thúc trò chơi\nChưa thể xem đáp án");
				} else if (e.getSource() == btnFinish) {

					if (!isFinish) {
						timer.stop();
						isFinish = true;
                                               
						playSound("sound/finish.wav");
//                                                int a=gridPlay.checkAfterFinish();
//                                                totalScore=totalScore+a;
//                                                validate();
//                                                doc.remove(0, doc.getLength());
//						doc.insertString(0, "      " + totalScore, doc
//								.getStyle("special"));

						 JOptionPane.showMessageDialog(topBox,
                         "Bạn được   : "+totalScore+" điểm\n" +
                         "Điểm thưởng: "+ bonusScore()+" điểm\n" +
                         "Hoàn thành : "+(bonusScore()+totalScore)*100/maxScore+" %\n"+
                         "Thời gian  : "+timeUse()/60+" phút "+timeUse()%60+" giây"
                        ,"Finish",JOptionPane.INFORMATION_MESSAGE,new ImageIcon(this.getClass().getResource("/img/score.png")));
					}

				}
			} catch (Exception m) {
			}
			;
		}
	}

	class SquareListener implements MouseListener {
		public void mouseClicked(MouseEvent e) {
			Square sq = (Square) e.getSource();
                       gridPlay.setSelectedWord(sq.getWord());
			if (sq.getBackground() == Color.BLACK)
			   clueTextPane.setText(gridPlay.getThemeName(gridPlay.getCrossword()));
                        else if (gridPlay.getSelectedWord() == gridPlay.getKey()&&gridPlay.getKey().getIsHint())
                            clueTextPane.setText(gridPlay.getKeywordClue());
                        else if (gridPlay.getSelectedWord() == gridPlay.getKey()&&!gridPlay.getKey().getIsHint())
                            clueTextPane.setText("Muốn xem gợi ý từ khóa bạn sẽ bị trừ 20đ");
			else {
				if (gridPlay.getClueUsed() == 0 || gridPlay.getClueUsed() == 1) {
					String s1 = gridPlay.getSelectedClue1();
					clueTextPane.setText(s1);
					gridPlay.setClueUsed(1);
				}
				if (gridPlay.getClueUsed() == 2) {
					String s2 = gridPlay.getSelectedClue2();
					clueTextPane.setText(s2);
				}
				if (gridPlay.getClueUsed() == 3) {
					String s3 = gridPlay.getSelectedClue3();
					clueTextPane.setText(s3);
				}
				validate();
		       }
		 
             }

		public void mouseEntered(MouseEvent e) {
		}

		public void mouseExited(MouseEvent e) {
		}

		public void mousePressed(MouseEvent e) {
		}

		public void mouseReleased(MouseEvent e) {
		}

	}
}
